package leetCode.hw.string;

import java.util.ArrayList;
import java.util.List;

public class HJ18Solution {

    public static int[] statKind(List<String> arrs) {
        int[] result = new int[7];
        for(String str:arrs) {
            String[] params = str.split("~");
            if(!isRightSubIntnet(params[1])){
                result[5]+=1;
                continue;
            }
            int n = kindOf(params[0]);
            if(n==-2) {
                result[5]+=1;
            }
            else {
                result[n]+=1;
                if(isPrivateIntnet(params[0])){
                    result[6]+=1;
                }
            }
        }
        return result;
    }

    public static int[] A = {1, 126};
    public static int[] B = {128, 191};
    public static int[] C = {192, 223};
    public static int[] D = {224, 239} ;
    public static int[] E = {240, 255};

    public static List<Integer> getNums(String str) {
        String[] strs = str.split("\\.");
        List<Integer> nums = new ArrayList<>(4);
        for (String s : strs) {
            try {
                nums.add(Integer.parseInt(s));
            } catch (Exception ignore) {}
        }
        return nums;
    }

    /**
     * 分析类别
     * @param str
     * @return
     */
    public static int kindOf(String str) {
        int result = -2;
        List<Integer> nums = getNums(str);
        if (nums.size() == 4) {
            result = -1;
            int num = nums.get(0);
            if (num >= A[0] && num <= A[1]) result = 0;
            else if (num >= B[0] && num <= B[1]) result = 1;
            else if (num >= C[0] && num <= C[1]) result = 2;
            else if (num >= D[0] && num <= D[1]) result = 3;
            else if (num >= E[0] && num <= E[1]) result = 4;
            for (int i = 3; i > 0; i--) {
                if (nums.get(i) < 0 || nums.get(i) > 255) {
                    result = -1;
                    break;
                }
            }
        }
        return result;
    }

    // 判断子网掩码
    public static boolean isRightSubIntnet(String str) {
        boolean result = true;
        List<Integer> nums = getNums(str);
        boolean zore = false;
        if (nums.size() != 4) return false;
        for (int num : nums) {
            String binary = Integer.toBinaryString(num);
            if (binary.length() == 8 && !zore) {
                if (binary.contains("0")) zore = true;
            } else if (zore && binary.length() == 8) {
                result = false;
                break;
            } else {
                if (!"0".equals(binary)) {
                    result = false;
                    break;
                }
            }
        }
        return result;
    }

    // 判断是否时私网IP
    public static boolean isPrivateIntnet(String str) {
        boolean result = true;
        List<Integer> nums = getNums(str);
        if (nums.size() != 4) return false;
        int one = nums.get(0);
        int two = nums.get(1);
        switch (one) {
            case 10:
                for (int i = 1; i < nums.size(); i++) {
                    if (nums.get(i) < 0 || nums.get(i) > 255) {
                        result = false;
                        break;
                    }
                }
                break;
            case 172:
                if (two < 16 || two > 31) result =  false;
                for (int i = 2; i < nums.size(); i++) {
                    if (nums.get(i) < 0 || nums.get(i) > 255) {
                        result = false;
                        break;
                    }
                }
                break;
            case 192:
                if (two != 168) result =  false;
                for (int i = 2; i < nums.size(); i++) {
                    if (nums.get(i) < 0 || nums.get(i) > 255) {
                        result = false;
                        break;
                    }
                }
                break;
            default: result = false;
        }
        return result;
    }

}
